package com.code.springbootmybatismysql.configuration.datasource;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * 定义数据源的AOP切面,通过该 dao 的方法名判断是应该走读库还是写库
 */
@Component
@Aspect
public class DataSourceAop {
    private Logger logger = LoggerFactory.getLogger(DataSourceAop.class);

    @Before("execution(* com.code.springbootmybatismysql..*mapper..*.*(..))")
    public void before(JoinPoint joinPoint) {
        logger.info("Aop --> before");
        Object target = joinPoint.getTarget();

        if (target == null) {
            return;
        }

        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
        String methodName = joinPoint.getSignature().getName();
        if (method != null && method.isAnnotationPresent(DataSource.class)) {
            DataSource dataSource = method.getAnnotation(DataSource.class);
            DbContextHolder.setDataSource(dataSource.value());
        } else if (methodName.startsWith("find") || methodName.startsWith("query")
                || methodName.startsWith("get") || methodName.startsWith("list")
                || methodName.startsWith("select")) {
            DbContextHolder.setDataSource(DBEnum.SLAVE1.getType());
        } else {
            DbContextHolder.setDataSource(DBEnum.MASTER.getType());
        }

        logger.info("aop --> ds = {}", DbContextHolder.getDataSource());
    }

    @After("execution(* com.code.springbootmybatismysql..*mapper..*.*(..))")
    public void after(JoinPoint joinPoint) {
        logger.info("Aop --> after");
        DbContextHolder.setDataSource(DBEnum.MASTER.getType());
    }
}
